package io.renren.modules.sys.service.impl;

import com.google.common.collect.Maps;
import io.renren.common.utils.ShiroUtils;
import io.renren.modules.sys.bottom.BottomRuleUtils;
import io.renren.modules.sys.bottom.BottomStatusEnum;
import io.renren.modules.sys.config.SysBottomConfig;
import io.renren.modules.sys.entity.*;
import io.renren.modules.sys.service.SysUserService;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;

import io.renren.modules.sys.dao.SysBottomUserDao;
import io.renren.modules.sys.service.SysBottomUserService;


@Service("sysBottomUserService")
public class SysBottomUserServiceImpl implements SysBottomUserService {

	@Autowired
	private SysBottomUserDao sysBottomUserDao;

	@Autowired
	private SysBottomConfig sysBottomConfig;

	@Autowired
	private SysUserService sysUserService;
	
	@Override
	public SysBottomUserEntity queryObject(Long bottomId){
		return sysBottomUserDao.queryObject(bottomId);
	}
	
	@Override
	public List<SysBottomUserEntity> queryList(Map<String, Object> map){
		return sysBottomUserDao.queryList(map);
	}
	
	@Override
	public int queryTotal(Map<String, Object> map){
		return sysBottomUserDao.queryTotal(map);
	}
	
	@Override
	public void save(SysBottomUserEntity sysBottomUser){
		sysBottomUserDao.save(sysBottomUser);
	}
	
	@Override
	public void update(SysBottomUserEntity sysBottomUser){
		sysBottomUserDao.update(sysBottomUser);
	}
	
	@Override
	public void delete(Long bottomId){
//		sysBottomUserDao.delete(bottomId);
	}
	
	@Override
	public void deleteBatch(Long[] bottomIds){
//		sysBottomUserDao.deleteBatch(bottomIds);
	}

	/**
	 * 用户下注
	 * @param bottomList 下注列表
	 * @param sysBottomEntity 期数
	 */
	@Override
	public void bottom(List<SysOddsCatetoryEntity> bottomList, SysBottomEntity sysBottomEntity) {

		for (SysOddsCatetoryEntity sysOddsCatetoryEntity : bottomList) {

			SysBottomUserEntity sysBottomUserEntity = new SysBottomUserEntity();
			sysBottomUserEntity.setBottomId(sysBottomEntity.getBottomId());
			sysBottomUserEntity.setUserId(ShiroUtils.getUserId());
			sysBottomUserEntity.setBottomName(sysBottomEntity.getBottomName());
			sysBottomUserEntity.setName(sysOddsCatetoryEntity.getName());
			sysBottomUserEntity.setStatus(BottomStatusEnum.WAITING.getCode());
			sysBottomUserEntity.setWaterBreak(SysBottomConfig.DEFAULT_WATER_BREAK);

			for (SysOddsEntity sysOddsEntity : sysOddsCatetoryEntity.getList()) {

				sysBottomUserEntity.setNumber(sysOddsEntity.getName());

				Long amount = sysOddsEntity.getMoney().longValue() * 100;
				Double odds = getBottomOdds(sysBottomUserEntity);
				//可赢金额 = 下注金额 * 赔率 - 本金 - 退水。退水 = 下注金额 * 0.5%
				Long winAmount = (long)(amount * (odds - 1) - amount * SysBottomConfig.DEFAULT_WATER_BREAK);

				sysBottomUserEntity.setAmount(amount);
				sysBottomUserEntity.setOdds(odds);
				sysBottomUserEntity.setWinAmount(winAmount);

				if (sysUserService.bottom(sysBottomUserEntity.getUserId(), sysBottomUserEntity.getAmount())) {
					save(sysBottomUserEntity);
				}
			}

		}
	}

	/**
	 * 开奖
	 * @param sysBottomEntity 开奖信息
	 */
	@Override
//	@Transactional
	public void lottery(SysBottomEntity sysBottomEntity) {

		int limit = 10;
		int offset = 0;
		Map<String, Object> param = Maps.newHashMap();

		while (true) {
			param.put("offset", offset);
			param.put("limit", 10);
			param.put("bottomId", sysBottomEntity.getBottomId());

			List<SysBottomUserEntity> list = queryList(param);
			if (CollectionUtils.isEmpty(list)) {
				break;
			}
			for (SysBottomUserEntity sysBottomUserEntity : list) {

				String winNumber = sysBottomEntity.getBottomNumber();
				String firstName = sysBottomUserEntity.getName();
				String number = sysBottomUserEntity.getNumber();

				SysBottomUserEntity updateParam = new SysBottomUserEntity();
				updateParam.setId(sysBottomUserEntity.getId());

				if (BottomRuleUtils.check(winNumber, firstName, number)) {
					updateParam.setStatus(BottomStatusEnum.WIN.getCode());
				}else {
					updateParam.setStatus(BottomStatusEnum.NOT_WIN.getCode());
					updateParam.setWinAmount(-sysBottomUserEntity.getWinAmount());
				}
				update(updateParam);

				sysBottomUserEntity.setStatus(updateParam.getStatus());

				allotUser(sysBottomUserEntity);
			}

			offset += limit;
		}
	}

	@Override
	public SysBottomUserEntity querAmountTotal(Map<String, Object> param) {
		return sysBottomUserDao.queryAmountTotal(param);
	}

	@Override
	public List<SysBottomTotalEntity> querySumList(Map<String, Object> param) {
		return sysBottomUserDao.querySumList(param);
	}

	/**
	 * 用户中奖
	 * @param sysBottomUserEntity 投注信息
	 */
	private void allotUser(SysBottomUserEntity sysBottomUserEntity) {

		long amount = sysBottomUserEntity.getAmount();
		long winAmount = sysBottomUserEntity.getWinAmount();

		if (sysBottomUserEntity.getStatus() == BottomStatusEnum.WIN.getCode()) {
			sysUserService.updateUserBalance(sysBottomUserEntity.getUserId(), winAmount + amount);
		}

		sysUserService.updateUserStayBalance(sysBottomUserEntity.getUserId(), -amount);
	}

	/**
	 * 获取赔率
	 * @param sysBottomUserEntity 下注信息
	 * @return
	 */
	private Double getBottomOdds(SysBottomUserEntity sysBottomUserEntity) {
		String key = sysBottomUserEntity.getName() + "_" + sysBottomUserEntity.getNumber();
		return sysBottomConfig.getKeyMap().getOrDefault(key, 1D);
	}

}
